import re
from rest_framework.views import APIView
from django.core.cache import cache
from django.conf import settings

from . import serializers, models, throttles
from utils.response import APIResponse
from libs import tx_sms



# 多方式登陆
class LoginAPIView(APIView):
    def post(self,request,*args,**kwargs):
        # 使用序列化类校验登陆数据
        ser_obj = serializers.LoginModelSerializer(data=request.data)
        if not ser_obj.is_valid():
            return APIResponse(1, "登陆失败", results=ser_obj.errors, http_status=400)
        return APIResponse(results={
            "username": ser_obj.user.username,
            "token": ser_obj.token
        })


# 发送短信
from celery_task import send_sms_task
class SMSAPIView(APIView):
    throttle_classes = [throttles.SMSRateThrottle]
    def post(self,request,*args,**kwargs):
        mobile = request.data.get('mobile')

        # 因为re匹配的时候只能匹配字符串，因此转成str
        if isinstance(mobile, int):
            mobile = str(mobile)
        if not (mobile and re.match(r'^1[3-9][0-9]{9}$', mobile)):
            return APIResponse(2, '手机号格式有误')
        # 获取验证码
        code = tx_sms.get_code()
        # 发送验证码接口
        # result = tx_sms.send_sms(mobile, code, settings.SMS_EXP // 60)
        # if not result:
        #     return  APIResponse(1,"验证码发送失败")

        # 使用celery框架完成发送短信验证码
        result = send_sms_task.delay(mobile, code, settings.SMS_EXP // 60)
        print(result)   # id号

        # 设置服务器缓存验证码, key,value,exp
        cache.set(f"sms_{mobile}", code, settings.SMS_EXP)
        # 校验发送的验证码与缓存的验证码是否一致
        print('>>>> %s - %s <<<<' % (code, cache.get('sms_%s' % mobile)))
        return APIResponse(0, '发送验证码成功')


# 手机验证码登陆
class LoginMobileAPIView(APIView):
    def post(self,request,*args,**kwargs):
        # 使用序列化类校验登陆数据
        ser_obj = serializers.CodeLoginModelSerializer(data=request.data)
        if not ser_obj.is_valid():
            return APIResponse(1, "登陆失败", results=ser_obj.errors, http_status=400)
        return APIResponse(results={
            "username": ser_obj.user.username,
            "token": ser_obj.token
        })


# 注册
class RegisterAPIView(APIView):
    def post(self,request,*args,**kwargs):
        # 反序列化
        ser_obj = serializers.RegisterModelSerializer(data=request.data)
        if ser_obj.is_valid():
            # 数据库存储
            ser_obj.save()
            return APIResponse(results="注册成功")
        return APIResponse(1, "注册失败", results=ser_obj.errors, http_status=400)



# 手机号校验
class MobileAPIView(APIView):
    def post(self,request,*args,**kwargs):
        mobile = request.data.get('mobile')
        if not (mobile and re.match(r'^1[3-9][0-9]{9}$', mobile)):
            return APIResponse(2, '手机号格式有误')
        try:
            # 已经注册了
            models.User.objects.get(mobile=mobile) # get取不到直接报错
            return APIResponse(1, '手机已注册')  # 不设置错误状态码是因为可能登陆都要用
        except:
            # 没有注册过
            return APIResponse(0, '手机未注册')  # 不设置错误状态码是因为可能登陆都要用
